package xin.lhuo.we.server.service.impl;

import com.github.pagehelper.PageHelper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.qiniu.common.QiniuException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import xin.lhuo.we.server.dao.DocumentMapper;
import xin.lhuo.we.server.dao.FolderMapper;
import xin.lhuo.we.server.entity.Document;
import xin.lhuo.we.server.entity.Folder;
import xin.lhuo.we.server.entity.QiNiuPutRet;
import xin.lhuo.we.server.enums.QiNiuCodeEnum;
import xin.lhuo.we.server.enums.ResultEnum;
import xin.lhuo.we.server.exception.WeException;
import xin.lhuo.we.server.properties.QiNiuProperties;
import xin.lhuo.we.server.service.IDocumentService;
import xin.lhuo.we.server.utils.InputStreamUtil;
import xin.lhuo.we.server.utils.MimeTypeUtil;
import xin.lhuo.we.server.utils.PageBean;
import xin.lhuo.we.server.utils.QiNiuUtil;

import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import static xin.lhuo.we.server.enums.ResultEnum.*;

/**
 * @author Lhuo
 * @date 2019/5/25 16:20
 */
@Service
@Slf4j
public class DocumentServiceImpl implements IDocumentService {
    private final FolderMapper folderMapper;
    private final QiNiuProperties qiNiuProperties;
    private final DocumentMapper documentMapper;

    public DocumentServiceImpl(FolderMapper folderMapper, QiNiuProperties qiNiuProperties, DocumentMapper documentMapper) {
        this.folderMapper = folderMapper;
        this.qiNiuProperties = qiNiuProperties;
        this.documentMapper = documentMapper;
    }

    @Override
    public void createFolder(Integer userId, String folderName) {
        if (folderMapper.checkFolderByNameAndUserId(userId, folderName) > 0) {
            throw new WeException(ResultEnum.PARAM_ERROR.getCode(), "文件名已存在");
        }
        Folder folder = new Folder();
        folder.setName(folderName);
        folder.setUserId(userId);
        folder.setCreateTime(new Date());
        folder.setUpdateTime(new Date());
        folderMapper.saveFolder(folder);
    }

    @Override
    public List<Folder> getFolder(Integer userId) {
        return folderMapper.getFolderByUserId(userId);
    }

    @Override
    public void renameFolder(Integer id, String folderName, Integer userId) {
        if (folderMapper.checkFolderByIdAndUserId(userId, id) != 1) {
            throw new WeException(ResultEnum.PARAM_ERROR.getCode(), "该文件夹不存在");
        }
        if (folderMapper.checkFolderByNameAndUserId(userId, folderName) > 0) {
            throw new WeException(ResultEnum.PARAM_ERROR.getCode(), "文件名已存在");
        }
        folderMapper.renameFolder(id, folderName);
    }

    @Override
    public void deleteFolder(Integer id, Integer userId) {
        if (folderMapper.checkFolderByIdAndUserId(userId, id) != 1) {
            throw new WeException(ResultEnum.PARAM_ERROR.getCode(), "该文件夹不存在");
        }
        if (documentMapper.checkDocumentByFolderId(id) != 0){
            throw new WeException(PARAM_ERROR.getCode(),"文件不能为空");
        }
        folderMapper.deleteFolder(userId, id);
    }

    @Override
    public String getUpdateToken() {
        try {
            return QiNiuUtil.getUpTokenByDocument(qiNiuProperties);
        } catch (Exception e) {
            throw new WeException(QINIU_TOKEN_FAIL.getCode(), "七牛token获取失败");
        }
    }

    @Override
    public void saveDocument(String authorization, InputStream inputStream) throws Exception {
        HashMap<String, String> result = new HashMap<>(1);
        byte[] bodyByte = InputStreamUtil.inputStreamToByte(inputStream);
        // 1. 验证是否为七牛的回调;
        if (QiNiuUtil.isValidDocCallback(qiNiuProperties, authorization, bodyByte)) {
            // 2. 数据流转换成Object;
            log.debug("body {}", new String(bodyByte));
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
            QiNiuPutRet qiNiuPutRet = gson.fromJson(new String(bodyByte), QiNiuPutRet.class);
            log.debug("qiNiuPutRet: {}", qiNiuPutRet.toString());

            // 3. 将数据保存到数据库
            Document document = new Document();
            document.setUserId(qiNiuPutRet.getUserId());
            document.setFolderId(qiNiuPutRet.getFolderId());
            String key = qiNiuPutRet.getKey();
            String name = key.substring(key.lastIndexOf('_') + 1, key.length());
            document.setName(name);
            document.setKey(key);
            document.setSize(qiNiuPutRet.getFsize());
            document.setMimeType(qiNiuPutRet.getMimeType());
            document.setSimpleType(MimeTypeUtil.getSimpleType(qiNiuPutRet.getMimeType()));
            document.setLastModifiedDate(qiNiuPutRet.getLastModifiedDate());
            document.setETag(qiNiuPutRet.getHash());
            document.setCreateTime(new Date());
            document.setUpdateTime(new Date());
            documentMapper.saveDoc(document);
        } else {
            log.error("验证上传照片回调失败");
            throw new WeException(PARAM_ERROR.getCode(), "此请求不是七牛发起的");
        }
    }

    @Override
    public List<Document> getDocuments(Integer folderId) {
        List<Document> documentList =  documentMapper.getDocumentByFolderId(folderId);
        for (Document document: documentList){
            String url = QiNiuUtil.getDownloadUrl(qiNiuProperties,qiNiuProperties.getBaseUrl()+document.getKey());
            document.setUrl(url);
        }
        return documentList;
    }

    @Override
    public PageBean<Document> getDocumentPages(Integer folderId, int currentPage, int pageSize) {
        PageHelper.startPage(currentPage,pageSize);
        List<Document> documentList = getDocuments(folderId);
        int countNums = documentMapper.getDocumentCountByFolderId(folderId);
        PageBean<Document> pageData = new PageBean<>(currentPage,pageSize,countNums);
        pageData.setItems(documentList);
        return pageData;
    }

    @Override
    public void deleteDocument(Integer id, Integer userId,String key) {
        if (documentMapper.checkDocumentById(id,userId) !=1){
            throw  new WeException(PARAM_ERROR.getCode(),"文件不存在");
        }
        documentMapper.deleteById(id);
        try {
            QiNiuUtil.deleteFile(qiNiuProperties,key);
        } catch (QiniuException e) {
            e.printStackTrace();
            if (e.response.statusCode != QiNiuCodeEnum.RESOURCES_NOT_EXIST.getCode()) {
                throw new WeException(ResultEnum.QI_NIU_DELETE_ERROR);
            }
        }
    }

    @Override
    public void renameDocument(Integer id, String name, Integer userId) {
        if (documentMapper.checkDocumentById(id,userId) !=1){
            throw  new WeException(PARAM_ERROR.getCode(),"文件不存在");
        }
        documentMapper.renameDocument(id, name);
    }
}
